package translate;

import temp.Label;
import temp.Temp;
import tree.BasicExp;
import tree.BasicStm;
import tree.CONST;
import tree.ESEQ;
import tree.EXP;
import tree.JUMP;
import tree.LABEL;
import tree.MOVE;
import tree.SEQ;
import tree.TEMP;

public class IfThenElseExp extends Exp {
	Exp cond, tc, ec;
	
	public IfThenElseExp(Exp c, Exp t, Exp e) {
		cond = c; tc = t; ec = e;
	}

	BasicStm unCx(Label tt, Label ff) {
		Label t = new Label();
		Label f = new Label();
		
		if (ec instanceof translate.IntExp && tc instanceof translate.IntExp) {
			int elcon= ((CONST)ec.unEx()).value;
			int thcon = ((CONST)tc.unEx()).value;
			if (elcon == 0) f = ff; else f = tt;
			if (thcon == 0) t = ff; else t = tt;
			return cond.unCx(t, f);
		}
		if (ec instanceof translate.IntExp) {
			int elcon= ((CONST)ec.unEx()).value;
			if (elcon == 0)
				return new SEQ(cond.unCx(t, ff), new SEQ(new LABEL(t), tc.unCx(tt, ff)));
			else
				return new SEQ(cond.unCx(t, tt), new SEQ(new LABEL(t), tc.unCx(tt, ff)));
		}
		if (tc instanceof translate.IntExp) {
			int thcon = ((CONST)tc.unEx()).value;
			if (thcon == 0)
				return new SEQ(cond.unCx(ff, f), new SEQ(new LABEL(f), ec.unCx(tt, ff)));
			else
				return new SEQ(cond.unCx(tt, f), new SEQ(new LABEL(f), ec.unCx(tt, ff)));
		}
		return new SEQ(cond.unCx(t, f), new SEQ(new LABEL(t), new SEQ(
				tc.unCx(tt, ff), new SEQ(new LABEL(f), ec.unCx(tt, ff)))));
	}

	BasicExp unEx() {
		Label t = new Label();
		Label f = new Label();
		Label join = new Label();
		Temp r = new Temp();
		BasicStm eclause = new SEQ(new LABEL(f), new SEQ(new MOVE(new TEMP(r), ec.unEx()), new LABEL(join)));
		BasicStm tclause = new SEQ(new LABEL(t), new SEQ(new MOVE(new TEMP(r), tc.unEx()), new SEQ(new JUMP(join), eclause)));
		return new ESEQ(new SEQ(cond.unCx(t, f),tclause), new TEMP(r));
	}

	BasicStm unNx() {
		Label t = new Label();
		Label f = new Label();
		Label join = new Label();
		BasicStm eclause, tclause;
		
		if (ec instanceof translate.IntExp && tc instanceof translate.IntExp)
			return new EXP(new CONST(0));
		if (ec instanceof translate.IntExp) {
			tclause = new SEQ(new LABEL(t), new SEQ(tc.unNx(), new JUMP(join)));
			return new SEQ(cond.unCx(t, join), tclause);
		}
		if (tc instanceof translate.IntExp) {
			eclause = new SEQ(new LABEL(f), new SEQ(ec.unNx(), new JUMP(join)));
			return new SEQ(cond.unCx(join, f), eclause);
		}
		eclause = new SEQ(new LABEL(f), new SEQ(ec.unNx(), new LABEL(join)));
		tclause = new SEQ(new LABEL(t), new SEQ(tc.unNx(), new SEQ(new JUMP(join), eclause)));
		return new SEQ(cond.unCx(t, f), tclause);
	}

}
